package com.gict.antifraudback.controller.front.article;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gict.antifraudback.entity.*;
import com.gict.antifraudback.exception.MyException;
import com.gict.antifraudback.result.ResultView;
import com.gict.antifraudback.service.*;
import com.gict.antifraudback.vo.ArticleVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ThinkPad
 */
@RestController
@Slf4j
@RequestMapping("/mapi/article")
public class FrontArticleController {

    @Autowired
    private ArticleService articleService;
    @Autowired
    private TagsService tagsService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private ArticleTagsService articleTagsService;
    @Autowired
    private LikeRecordService likeRecordService;
    @Autowired
    private ArticleCommentService articleCommentService;
    @Autowired
    private QuestionService questionService;
    @Autowired
    private UserService userService;

    @PostMapping("/getList")
    public ResultView getList(@RequestBody ArticleVo articleVo) {
//        TODO 待做查询优化
        String keywords = articleVo.getKeywords();

        LambdaQueryWrapper<Article> wrapper = Wrappers.lambdaQuery();
        wrapper.like(!ObjectUtils.isEmpty(articleVo.getArticleTitle()), Article::getArticleTitle, articleVo.getArticleTitle());
        wrapper.eq(articleVo.getContentType() != null, Article::getContentType, articleVo.getContentType());
        wrapper.eq(articleVo.getType() != null, Article::getType, articleVo.getType());
        wrapper.eq(articleVo.getUserId() != null, Article::getUserId, articleVo.getUserId());
        wrapper.eq(articleVo.getMenuId() != null, Article::getMenuId, articleVo.getMenuId());
        wrapper.like(!ObjectUtils.isEmpty(articleVo.getArticleTitle()), Article::getArticleTitle, articleVo.getArticleTitle());
        IPage<Article> page = articleService.page(new Page<>(articleVo.getCurrent(), articleVo.getPageSize()), wrapper);
        List<Article> records = page.getRecords();
        userService.setUserName(records);

        return ResultView.ok(page);
    }

    /**
     * 根据标签获取文章
     * @return
     */
    @PostMapping("/getListByTag")
    public ResultView getListByTag(@RequestBody ArticleVo articleVo) {
        if (articleVo.getTagId() != null){
            LambdaQueryWrapper<ArticleTags> wrapper = Wrappers.lambdaQuery();
            wrapper.like(ArticleTags::getTagId, articleVo.getTagId());
            IPage<ArticleTags> page = articleTagsService.page(new Page<>(articleVo.getCurrent(), articleVo.getPageSize()), wrapper);
            List<ArticleTags> records = page.getRecords();
            Page<Article> result = new Page<>();
            List<Article> records1 = result.getRecords();
            userService.setUserName(records1);
            BeanUtils.copyProperties(page, result);
            if (!records.isEmpty()){
                List<Integer> articleIds = records.stream().map(ArticleTags::getArticleId).collect(Collectors.toList());
                result.setRecords(new ArrayList<>(articleService.listByIds(articleIds)));
            }
            return ResultView.ok(result);
        }else {
            return ResultView.ok(articleService.page(new Page<>(articleVo.getCurrent(), articleVo.getPageSize()), Wrappers.emptyWrapper()));
        }
    }

    /**
     * 获取全部文章
     * @return
     */
    @GetMapping("/getListAll")
    public ResultView getListAll(ArticleVo articleVo) {
        return ResultView.ok(articleService.page(new Page<>(articleVo.getCurrent(), articleVo.getPageSize()), Wrappers.emptyWrapper()));
    }

    @GetMapping("/get")
    public ResultView get(@Valid @NotNull Integer id) {
        Article article = articleService.getById(id);
        if (article == null) {
            throw new MyException("文章不存在");
        }

        // 修改阅读量 fixme 应该优化存储逻辑
        article.setReadingQuantity(article.getReadingQuantity() + 1);
        articleService.updateById(article);

        // 设置点赞数
        article.setLikeCount(likeRecordService.countByArticleId(article.getId()));
        // 设置评论数
        article.setCommentCount(articleCommentService.countByArticleId(article.getId()));
        return ResultView.ok(article);
    }

    /**
     * 获取主页列表
     *
     * @return
     */
    @GetMapping("/getHomeList")
    public ResultView getHomeList() {
        //1置顶文章，2普通文章，3 全部标签 4 菜单反转
        List<Object> result = new ArrayList<>();
        // 置顶文章
        Map<String, Object> topArticle = new HashMap<>();
        topArticle.put("type", "1");
        topArticle.put("name", "置顶文章");
        List<Article> list = articleService.list(Wrappers.<Article>lambdaQuery().eq(Article::getIsTop, 1).eq(Article::getStatus, 1).ne(Article::getContentType, 2).orderByDesc(Article::getCreateTime).last("limit 3"));
        userService.setUserName(list);
        tagsService.setTagsName(list);
        topArticle.put("list", list);
        result.add(topArticle);

        // 推荐文章 TODO 推荐文章应该写一套规则
        Map<String, Object> recommendArticle = new HashMap<>();
        recommendArticle.put("type", "2");
        recommendArticle.put("name", "推荐文章");
        List<Article> recommendArticleList = articleService.list(Wrappers.<Article>lambdaQuery().eq(Article::getStatus, 1).ne(Article::getContentType, 2).orderByDesc(Article::getCreateTime).last("limit 8"));
        userService.setUserName(recommendArticleList);
        tagsService.setTagsName(recommendArticleList);
        recommendArticle.put("list", recommendArticleList);
        result.add(recommendArticle);

        // 全部标签
        Map<String, Object> allTags = new HashMap<>();
        allTags.put("type", "3");
        allTags.put("name", "全部标签");
        allTags.put("list", tagsService.list());
        result.add(allTags);

        // 菜单列表
        Map<String, Object> allMenus = new HashMap<>();
        allMenus.put("type", "4");
        allMenus.put("name", "菜单列表");
        allMenus.put("list", menuService.buildTree(menuService.list()));
        result.add(allMenus);

        return ResultView.ok(result);
    }

    /**
     * 获取侧边栏文章
     */
    @GetMapping("/getSidebarList")
    public ResultView getSidebarList() {
        //1广告 2热门文章
        List<Object> result = new ArrayList<>();
        // 广告
        Map<String, Object> advertising = new HashMap<>();
        advertising.put("type", "1");
        advertising.put("pic", "https://static.linhaojun.top/aurora/articles/3ec095cd9b7bd3f766166a4db14160c6.jpg");
        result.add(advertising);

        // 热门文章 TODO 推荐文章应该写一套规则
        Map<String, Object> hotArticle = new HashMap<>();
        hotArticle.put("type", "2");
        hotArticle.put("title", "推荐文章");
        hotArticle.put("list", articleService.list(Wrappers.<Article>lambdaQuery().eq(Article::getStatus, 1).orderByDesc(Article::getCreateTime).last("limit 3")));
        result.add(hotArticle);

        return ResultView.ok(result);
    }

    /**
     * 获取侧边栏视频列表
     */
    @GetMapping("/getSidebarVideoList")
    public ResultView getSidebarVideoList() {
        // 获取随机十条数据
        List<Article> articleList = articleService.selectRandomTenByType(1);
        if (!articleList.isEmpty()){
            // fixme 需要优化成一次性查询
            for (Article article : articleList) {
                // 设置点赞数
                article.setLikeCount(likeRecordService.countByArticleId(article.getId()));
                // 设置评论数
                article.setCommentCount(articleCommentService.countByArticleId(article.getId()));
            }
        }
        return ResultView.ok(articleList);
    }

    /**
     * 获取菜单文章
     * @param id 菜单id
     */
    @GetMapping("/getMenuArticleList")
    public ResultView getMenuArticleList(@Valid @NotNull Integer id) {
        List<Object> result = new ArrayList<>();
        List<Menu> list = menuService.list(Wrappers.<Menu>lambdaQuery().eq(Menu::getId, id).or().eq(Menu::getParentId, id).orderByDesc(Menu::getCreateTime));
        if (CollectionUtils.isNotEmpty(list)){
            Map<Integer, Menu> menuMap = list.stream().collect(Collectors.toMap(Menu::getId, a -> a));
            // 父级菜单
            Menu parentMenu = menuMap.get(id);
            List<Integer> ids = list.stream().map(Menu::getId).collect(Collectors.toList());
            List<Article> articleList = articleService.list(Wrappers.<Article>lambdaQuery().eq(Article::getStatus, 1).in(Article::getMenuId, ids));
            // 添加一级
            Map<String, Object> parent = new HashMap<>();
            parent.put("id", parentMenu.getId());
            parent.put("name", parentMenu.getName());
            parent.put("list", new ArrayList<>());
            result.add(parent);
            if (CollectionUtils.isNotEmpty(articleList)){
                Map<Integer, List<Article>> menuToArticle = articleList.stream().collect(Collectors.groupingBy(Article::getMenuId));
                parent.put("list", menuToArticle.get(parentMenu.getId()));
                for (Menu menu : list) {
                    if (Objects.equals(menu.getId(), id)){
                        continue;
                    }
                    Map<String, Object> map = new HashMap<>();
                    map.put("id", parentMenu.getId());
                    map.put("name", parentMenu.getName());
                    map.put("childName", menu.getName());
                    map.put("childId", menu.getId());
                    map.put("list", menuToArticle.get(menu.getId()));
                    result.add(map);
                }
            }else{
                // 没有文章也需要给初始值
                for (Menu menu : list) {
                    if (Objects.equals(menu.getId(), id)){
                        continue;
                    }
                    Map<String, Object> map = new HashMap<>();
                    map.put("id", parentMenu.getId());
                    map.put("name", parentMenu.getName());
                    map.put("childName", menu.getName());
                    map.put("childId", menu.getId());
                    map.put("list", new ArrayList<>());
                    result.add(map);
                }
            }
        }

        return ResultView.ok(result);
    }

    /**
     * 获取题目
     * @param id 文章id
     */
    @GetMapping("/getQuestion")
    public ResultView getQuestion(@Valid @NotNull Integer id) {
        List<Question> questions = questionService.listQuestionByArticleId(id);
        return ResultView.ok(questions);
    }

    /**
     * 每日一练
     */
    @GetMapping("/everydayExercise")
    public ResultView everydayExercise() {
        return ResultView.ok(questionService.everydayExercise());
    }

    /**
     * 数量统计
     */
    @GetMapping("/quantitativeStatistics")
    public ResultView quantitativeStatistics() {
        Map<String, Integer> result = new HashMap<>();
        result.put("articleCount", articleService.count());
        result.put("classifyCount", menuService.count());
        result.put("tagsCount", tagsService.count());

        return ResultView.ok(result);
    }

    /**
     * 推荐文章（随机3篇）
     */
    @GetMapping("/recommendedArticles")
    public ResultView recommendedArticles() {
        return ResultView.ok(articleService.randomThreeArticle());
    }

}
